﻿using NAudio.Wave;

namespace EdgeTTS.Net.Utils;

public class AudioPlayer
{
    private readonly WaveStream _streamReader;
    private readonly WaveOutEvent _waveOut;
    private bool _isPaused;
    private long _pausedPosition; // 记录暂停时的位置

    public AudioPlayer(byte[] source, float volume = 1.0f)
    {
        var ms = new MemoryStream(source);
        _streamReader = new StreamMediaFoundationReader(ms);
        _waveOut = new WaveOutEvent();
        _waveOut.Init(_streamReader);
        _waveOut.Volume = volume;
    }

    public AudioPlayer(string path, float volume = 1.0f)
    {
        _streamReader = new AudioFileReader(path);
        _waveOut = new WaveOutEvent();
        _waveOut.Init(_streamReader);
        _waveOut.Volume = volume;
    }

    /// <summary>
    ///     播放音频
    /// </summary>
    public void Play()
    {
        if (_isPaused)
        {
            // 从暂停的位置继续播放
            _streamReader.Position = _pausedPosition;
            _isPaused = false;
        }
        else
        {
            _waveOut.Play();
        }

        while (_waveOut.PlaybackState == PlaybackState.Playing) Thread.Sleep(50);
    }

    /// <summary>
    ///     播放音频
    /// </summary>
    public async Task PlayAsync()
    {
        if (_isPaused)
        {
            // 从暂停的位置继续播放
            _streamReader.Position = _pausedPosition;
            _isPaused = false;
        }

        _waveOut.Play();

        while (_waveOut.PlaybackState == PlaybackState.Playing) await Task.Delay(50);
    }

    /// <summary>
    ///     暂停播放
    /// </summary>
    public void Pause()
    {
        if (_isPaused)
            return;
        
        _waveOut.Pause();
        _isPaused = true;
        // 记录暂停时的位置
        _pausedPosition = _streamReader.Position;
    }

    /// <summary>
    ///     重新播放
    /// </summary>
    public void Resume()
    {
        Stop();
        Play();
    }

    /// <summary>
    ///     停止播放
    /// </summary>
    public void Stop()
    {
        _waveOut.Stop();
        _pausedPosition = 0;
        _isPaused = false;
    }
}